package com.stars.easyms.datasource.pointcut;

import java.lang.annotation.Annotation;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * <p>className: EasyMsAnnotationMatchingPointcut</p>
 * <p>description: EasyMs注解匹配切点类</p>
 *
 * @author guoguifang
 * @version 1.2.1
 * @date 2019/5/10 14:56
 */
final class EasyMsAnnotationMatchingPointcut implements Pointcut {

    private final ClassFilter classFilter;

    private final MethodMatcher methodMatcher;

    EasyMsAnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType, @Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) {
        Assert.isTrue(classAnnotationType != null || methodAnnotationType != null, "Either Class annotation type or Method annotation type needs to be specified (or both)");
        if (classAnnotationType != null) {
            this.classFilter = new EasyMsAnnotationClassFilter(classAnnotationType, checkInherited);
        } else {
            this.classFilter = ClassFilter.TRUE;
        }

        if (methodAnnotationType != null) {
            this.methodMatcher = new EasyMsAnnotationMethodMatcher(methodAnnotationType, checkInherited);
        } else {
            this.methodMatcher = MethodMatcher.TRUE;
        }

    }

    @NonNull
    @Override
    public ClassFilter getClassFilter() {
        return this.classFilter;
    }

    @NonNull
    @Override
    public MethodMatcher getMethodMatcher() {
        return this.methodMatcher;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        } else if (!(other instanceof EasyMsAnnotationMatchingPointcut)) {
            return false;
        } else {
            EasyMsAnnotationMatchingPointcut otherPointcut = (EasyMsAnnotationMatchingPointcut) other;
            return this.classFilter.equals(otherPointcut.classFilter) && this.methodMatcher.equals(otherPointcut.methodMatcher);
        }
    }

    @Override
    public int hashCode() {
        return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
    }

    @Override
    public String toString() {
        return "EasyMsAnnotationMatchingPointcut: " + this.classFilter + ", " + this.methodMatcher;
    }
}
